<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        margin: 0;
        padding: 0;
      }
      canvas {
        border: 1px solid black;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
      attribute vec2 aPosition; // 位置坐标
      attribute vec4 aColor; // 颜色坐标
      varying vec4 vColor; // 颜色变量
      void main() {
        gl_Position = vec4(aPosition, 0.0, 1.0);
        vColor = aColor; // 设置颜色
      }
    </script>

    <!-- 片元着色器 -->
    <script id="fragment-shader" type="x-shader/x-fragment">
      precision highp float; // 设置精度
      varying vec4 vColor; // 颜色变量
      void main() {
        gl_FragColor = vColor; // 使用颜色变量
      }
    </script>
    <script>
      const canvas = document.getElementById("canvas");
      const gl = canvas.getContext("webgl");
      if (!gl) {
        console.error("WebGL not supported");
      }
      // 创建顶点着色器和片元着色器
      const vertexShader = gl.createShader(gl.VERTEX_SHADER);
      const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);

      //获取着色器代码
      const vertexSource = document.getElementById("vertex-shader").textContent;
      const fragmentSource =
        document.getElementById("fragment-shader").textContent;

      // 绑定着色器源码
      gl.shaderSource(vertexShader, vertexSource);
      gl.shaderSource(fragmentShader, fragmentSource);

      // 编译着色器
      gl.compileShader(vertexShader);
      gl.compileShader(fragmentShader);

      // 创建程序对象
      const program = gl.createProgram();
      // 将顶点着色器和片元着色器关联到程序对象
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);
      // 链接程序对象
      gl.linkProgram(program);
      // 使用程序对象
      gl.useProgram(program);

      // 创建顶点数据
      // 顶点坐标数据和颜色数据
      /*
        第一个顶点坐标和颜色信息:
        -0.5, 0.5, 1.0, 1.0, 0.0, 1.0
        第二个顶点坐标和颜色信息:
        0.5, -0.5, 0.0, 1.0, 0.0, 1.0
      */
      const vertices = new Float32Array([
        -0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0,
      ]);

      // 创建缓冲区对象
      const buffer = gl.createBuffer();
      // 绑定缓冲区对象 gl.ARRAY_BUFFER 表示一个顶点属性数组缓冲区，例如顶点坐标、顶点颜色等
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
      // 将数据传输到缓冲区对象
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

      // 获取属性位置
      const positionLocation = gl.getAttribLocation(program, "aPosition");
      // 启用属性
      gl.enableVertexAttribArray(positionLocation);
      // 指定属性指针
      gl.vertexAttribPointer(
        positionLocation, // index,属性位置
        2, // size,每个顶点的分量数量
        gl.FLOAT, // type,数据类型
        false, // 是否归一化
        6 * Float32Array.BYTES_PER_ELEMENT, // stride 步长，表示每个顶点的字节数
        0 // offset 偏移量，表示从缓冲区的哪个位置开始读取数据
      );

      // 获取颜色位置
      const colorLocation = gl.getAttribLocation(program, "aColor");
      // 启用颜色属性
      gl.enableVertexAttribArray(colorLocation);
      // 指定颜色属性指针
      gl.vertexAttribPointer(
        colorLocation,
        4,
        gl.FLOAT,
        false,
        6 * Float32Array.BYTES_PER_ELEMENT,
        2 * Float32Array.BYTES_PER_ELEMENT // 偏移量，表示从缓冲区的哪个位置开始读取颜色数据
      );

      // 绘制线段
      gl.drawArrays(gl.LINES, 0, 2); // 绘制线段
    </script>
  </body>
</html>
